<!doctype html>
<html lang="zh-cn">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>文件上传</title>
    <link rel="stylesheet" href="css/app.css">
    <script src="https://cdn.bootcss.com/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
    <script src="layer/layer.js"></script>
    <style>
        input,
        button {
            outline: none;
        }

        * {
            -moz-osx-font-smoothing: auto;
            -webkit-font-smoothing: antialiased;
        }

        .group-price {
            border: 1px solid #efefef;
            padding: 10px;
            box-sizing: border-box;
            width: 100%;
            overflow: hidden;
        }

        .group-price h4 {
            font-size: 14px;
            padding-bottom: 10px;
            margin: 0;
            border-bottom: 1px solid #efefef;
        }

        .group-label {
            display: flex;
            justify-content: flex-start;
            margin: 10px 0;
        }

        .group-label .labels {
            width: 80px;
            height: 30px;
            margin-right: 10px;
        }

        .group-label .labels input {
            display: none;
        }

        .group-label .labels label {
            display: block;
            text-align: center;
            line-height: 30px;
            font-size: 12px;
            cursor: pointer;
            border: 1px solid #2d8dff;
            box-sizing: border-box;
            color: #2d8dff;
        }

        .group-label .labels input[type="radio"]:checked+label {
            background-color: #2d8dff;
            color: #ffffff;
        }

        .group-only-style .form-group-style {
            height: 40px;
        }

        .group-only-style .form-group-style label {
            display: flex;
            justify-content: flex-start;
            align-items: center;
            height: 40px;
        }

        .group-only-style .form-group-style label strong {
            width: 100px;
            font-size: 12px;
            margin-right: 10px;
            text-align: right;
            color: #666666;
            font-weight: normal;
        }

        .group-only-style .form-group-style label input {
            flex: 1;
            height: 30px;
            border: none;
            border-bottom: 1px solid #efefef;
        }

        .group-only-style .form-group-style label input:focus {
            border-color: #2d8dff;
        }

        .group-model-style .group-type-title {
            display: flex;
            justify-content: space-between;
            align-items: center;
            height: 40px;
            border-bottom: 1px solid #efefef;
        }

        .group-type-add {
            height: 52px;
            padding: 5px 0;
            box-sizing: border-box;
            border-top: 1px solid #efefef;
            border-bottom: 1px solid #efefef;
            margin: 5px 0;
        }

        .group-type-add button {
            display: block;
            width: 100%;
            height: 40px;
            background-color: #2d8dff;
            color: #ffffff;
            border: none;
            cursor: pointer;
        }

        .group-type-add button:hover {
            background-color: #2d6aee;
        }

        .group-model-style .group-type-title h5 {
            margin: 0;
        }

        .group-model-style .group-type-title button {
            background-color: transparent;
            border: 1px solid #2d8dff;
            font-size: 12px;
            border-radius: 5px;
            color: #2d8dff;
            padding: 3px 10px;
            cursor: pointer;
            margin-right: 5px;
        }

        .group-model-style .group-type-title button:hover {
            background-color: #2d8dff;
            color: #ffffff;
        }

        .group-model-style .group-type-title button.group-del {
            color: red;
            border-color: red;
        }

        .group-model-style .group-type-title button.group-del:hover {
            background-color: red;
            color: #ffffff;
        }

        .group-model-style .group-type dl {
            display: flex;
            flex-flow: row wrap;
            margin: 10px 0;
        }

        .group-model-style .group-type dl dd {
            position: relative;
            border: 1px solid #efefef;
            color: #333333;
            font-size: 12px;
            padding: 6px 40px 6px 20px;
            margin: 0 5px 5px 0;
        }

        .group-model-style .group-type dl dd::after {
            position: absolute;
            content: "\2715";
            top: 3px;
            right: 5px;
            font-size: 16px;
            color: #efefef;
        }

        .group-model-style .group-type dl dd:hover {
            color: #ffffff;
            background-color: #2d8dff;
            cursor: pointer;
        }

        .group-model-style .group-type dl dd:hover::after {
            color: #ffffff;
        }

        .group-model-style table {
            width: 100%;
        }

        .group-model-style table th {
            font-size: 12px;
            text-align: center;
            border-bottom: 1px solid #a3a3a3;
            padding: 5px 0;
            white-space: nowrap;
        }

        .group-model-style table td {
            font-size: 12px;
            text-align: center;
            border-bottom: 1px solid #e3e3e3;
            padding: 5px 0;
            white-space: nowrap;
        }

        .group-model-style table td label {
            display: flex;
            text-align: center;
        }

        .group-model-style table td label input {
            flex: 1;
            height: 40px;
            padding: 0 5px;
            box-sizing: border-box;
            border: none;
            border-bottom: 1px solid transparent;
            text-align: center;
            color: #666666;
        }

        .group-model-style table td label input:focus {
            border-bottom-color: #2d8dff;
        }
    </style>
</head>

<body>
    <div id="root" class="group-price">
        <h4>规格</h4>
        <div class="group-label">
            <div class="labels">
                <input type="radio" value="10" :checked="onlyType" name="labels" id="only" @change="handleRadio">
                <label for="only">单规格</label>
            </div>
            <div class="labels">
                <input type="radio" value="20" :checked="!onlyType" name="labels" id="model" @change="handleRadio">
                <label for="model">多规格</label>
            </div>
        </div>

        <div class="group-only-style" v-show="onlyType">
            <div class="form-group-style">
                <label>
                    <strong>商品价格</strong>
                    <input type="text">
                </label>
            </div>
            <div class="form-group-style">
                <label>
                    <strong>商品划线价</strong>
                    <input type="text">
                </label>
            </div>
            <div class="form-group-style">
                <label>
                    <strong>当前库存数量</strong>
                    <input type="text">
                </label>
            </div>
            <div class="form-group-style">
                <label>
                    <strong>商品重量(Kg) </strong>
                    <input type="text">
                </label>
            </div>
        </div>

        <div class="group-model-style" v-show="!onlyType">
            <input type="hidden" v-model="groupAryVal">
            <input type="hidden" v-model="groupItemAryVal">
            <div class="group-add-type">
                <template v-for="(item_01,index) of groupArray" :key="index">
                    <div class="group-type">
                        <div class="group-type-title">
                            <h5>{{item_01.name}}</h5>
                            <div>
                                <button type="button" class="group-add" @click="handleClickAddKey" :data-index="index">
                                    添加规格值
                                </button>
                                <button type="button" class="group-del" @click="handleClockDelType" :data-index="index">
                                    删除
                                </button>
                            </div>
                        </div>
                        <dl>
                            <template v-for="(item_02,key) in item_01.type" :key="key">
                                <dd @click="handleClickDelItem" :data-first-index="index" :data-item-key="key">
                                    {{item_02}}
                                </dd>
                            </template>
                        </dl>
                    </div>
                </template>
            </div>

            <div class="group-type-add" v-show="maxType">
                <button type="button" @click="handleClickAddTypeGroup" data-index="11111">添加规格组</button>
            </div>

            <div class="group-table" v-show="groupArray.length">
                <table>
                    <thead>
                        <tr>
                            <template v-for="(item_03,index) in groupArray" :key="index">
                                <th v-if="Object.keys(item_03.type).length">{{item_03.name}}</th>
                            </template>
                            <th>详情图</th>
                            <th>划线价</th>
                            <th>现价</th>
                            <th>重量(Kg)</th>
                            <th>编码</th>
                        </tr>
                    </thead>
                    <tbody>
                        <template v-for="(item_04,index) in groupItemArray" :key="index">
                            <tr>
                                <template v-for="(item_05,key) in item_04" :key="key">
                                    <td
                                        v-if="key != 'code' && key != 'pic' && key != 'lint' && key != 'price' && key != 'spec' ">
                                        {{item_05}}
                                    </td>
                                </template>
                                <td>
                                    <img :src="item_04.pic" alt="" width="50" height="50" @click="handleClickImg"
                                        :data-index="index">
                                </td>
                                <td>
                                    <label><input type="text" value="100"
                                            v-model="groupItemArray[index]['lint']"></label>
                                </td>
                                <td>
                                    <label><input type="text" value="100"
                                            v-model="groupItemArray[index]['price']"></label>
                                </td>
                                <td>
                                    <label><input type="text" value="100"
                                            v-model="groupItemArray[index]['spec']"></label>
                                </td>
                                <td>{{item_04.code}}</td>
                            </tr>
                        </template>
                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <!--    <input type="submit" value="提交">-->
    <script type="text/javascript" defer="defer">
        // 当前商品是单规格还是多规格 单规格是true 多规格是false
        let onlyType = false,
            // 规格分类组
            groupArray = Array(),
            // 当前商品规格显示
            groupItemArray = Array();
        // 图片组
        var activeArray = Array();

        let vueDom = new Vue({
            el: "#root",
            data: {
                // 规格分类组 [{name: '颜色', type: [cc: '红色',dd: '绿色']},{name: '尺寸', type: [aa: 'S',bb: 'X']}]
                groupArray,
                // 产生规格商品组 [{code: 'cc&dd',cc:'红色',aa:'S',pic:'',lint:100,price:120,spec:50}]
                groupItemArray,
                // 当前商品规格显示
                onlyType,
                // 当前限定添加规格组
                maxType: true,
            },
            beforeMount: function () {
                this.onloadItemAry();
            },
            computed: {
                groupAryVal: function () {
                    return JSON.stringify(this.groupArray);
                },
                groupItemAryVal: function () {
                    return JSON.stringify(this.groupItemArray);
                }
            },
            methods: {
                // 点击切换单/多规格
                handleRadio: function (res) {
                    let that = this;
                    if (res.target.value === '10') {
                        that.onlyType = true;
                    } else if (res.target.value === '20') {
                        that.onlyType = false;
                    }
                    that.onloadItemAry();
                },

                // 点击添加规格组
                handleClickAddTypeGroup: function (res) {
                    let that = this;
                    layer.prompt({
                        title: "添加规格组"
                    }, function (val, index) {
                        that.groupArray.push({
                            name: val,
                            type: Object()
                        });
                        that.onloadItemAry();
                        layer.close(index);
                    });
                },

                // 添加规格组值
                handleClickAddKey: function (res) {
                    let that = this,
                        indexNum = res.target.dataset.index,
                        randStrAry = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'g', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'],
                        s1 = Math.round(Math.random() * 25),
                        s2 = Math.round(Math.random() * 25),
                        randStr = randStrAry[s1] + randStrAry[s2];
                    for (let i = 0; i < 1; i--) {
                        if (that.onlyCode(indexNum, randStr)) {
                            randStr = randStrAry[s1] + randStrAry[s2];
                        } else {
                            break;
                        }
                    }

                    layer.prompt({
                        title: "添加子规格"
                    }, function (val, index) {
                        that.$set(that.groupArray[indexNum].type, randStr, val);
                        that.onloadItemAry();
                        layer.close(index);
                    });
                },

                //删除规格组
                handleClockDelType: function (res) {
                    let that = this,
                        delIndex = res.target.dataset.index;
                    layer.confirm('您要删除规格组么？', {
                        icon: 7,
                        title: "删除"
                    }, function (index) {
                        that.groupArray.splice(Number(delIndex), 1);
                        that.onloadItemAry();
                        layer.close(index);
                    });
                },

                // 删除规格值
                handleClickDelItem: function (res) {
                    let that = this,
                        delKey = res.target.dataset.itemKey,
                        delFirstIndex = res.target.dataset.firstIndex;
                    layer.confirm('您要删除规格组么？', {
                        icon: 7,
                        title: "删除"
                    }, function (index) {
                        that.$delete(that.groupArray[delFirstIndex].type, delKey);
                        that.onloadItemAry();
                        layer.close(index);
                    });
                },

                // 上传图片
                handleClickImg: function (res) {
                    let that = this,
                        imgIndex = res.target.dataset.index;
                    layer.open({
                        type: 2, //类型
                        title: '图片管理', //标题
                        content: ['./upload.html', 'no'], //iframe的url，no代表不显示滚动条
                        area: ['893px', '580px'], //弹窗宽高
                        btn: ['确定', '取消'], //按钮
                        shade: [0.3], //遮罩透明度
                        shadeClose: false, //点击遮罩不关闭
                        id: 'upload',
                        anim: 2, //
                        yes: function (index) {
                            layer.close(index);
                            that.$set(that.groupItemArray[imgIndex], 'pic', activeArray[activeArray.length - 1].url);
                        },
                        btnAlign: 'l', //按钮位置
                        closeBtn: 0, //去掉关闭按钮
                    });
                },

                // 重新排列产品详情
                onloadItemAry: function () {
                    let that = this,
                        newGroupAry = Array(),
                        // 存储生成的skuArray
                        typeAry = Array(),
                        // 存储生成的sku
                        itemAry,
                        // 临时规格组
                        tmpGroupAry = Array(),
                        // 临时规格组二
                        tmpNewGroupAry = Array();

                    for (let item_09 of that.groupArray) {
                        let tmpAry = Array();
                        for (let key in item_09.type) {
                            if (item_09.type.hasOwnProperty(key)) {
                                tmpAry.push(key);
                            }
                        }
                        typeAry.push(tmpAry);
                    }

                    itemAry = that.descartes(typeAry);

                    for (let index in itemAry) {
                        if (itemAry.hasOwnProperty(index)) {
                            for (let item_11 of itemAry[index]) {
                                for (let item_12 of groupArray) {
                                    for (let key in item_12.type) {
                                        if (item_12.type.hasOwnProperty(key)) {
                                            if (item_11 === key) {
                                                if (tmpGroupAry.hasOwnProperty(index)) {
                                                    tmpGroupAry[index][key] = item_12.type[key];
                                                } else {
                                                    let tmpIte = Object();
                                                    tmpIte[key] = item_12.type[key];
                                                    tmpGroupAry.push(tmpIte);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    for (let item_13 of tmpGroupAry) {
                        let tmpCode = String(),
                            itemCodeGroup = Object(),
                            maxStr = 1;
                        for (let key in item_13) {
                            if (item_13.hasOwnProperty(key)) {
                                if (maxStr === Object.keys(item_13).length) {
                                    tmpCode += key;
                                } else {
                                    tmpCode += key + '&';
                                }
                                itemCodeGroup[key] = item_13[key];
                                ++maxStr;
                            }
                        }

                        let itemCode = {
                            code: tmpCode,
                            pic: 'http://tp.cn/upload/image/201912051575528498925234.jpeg',
                            lint: '0',
                            price: '0',
                            spec: '0'
                        };
                        for (let key in itemCodeGroup) {
                            if (itemCodeGroup.hasOwnProperty(key)) {
                                itemCode[key] = itemCodeGroup[key];
                            }
                        }
                        tmpNewGroupAry.push(itemCode)
                    }

                    for (let index_01 in tmpNewGroupAry) {
                        let c = Object();
                        if (groupItemArray.length === 0) {
                            c = tmpNewGroupAry[index_01];
                        } else {
                            for (let index_02 in groupItemArray) {
                                if (groupItemArray.hasOwnProperty(index_02)) {
                                    if (groupItemArray[index_02].code === tmpNewGroupAry[index_01].code) {
                                        let item = Object();
                                        for (let key in groupItemArray[index_02]) {
                                            if (groupItemArray[index_02].hasOwnProperty(key)) {
                                                item[key] = groupItemArray[index_02][key];
                                            }
                                        }
                                        c = item;
                                    } else {
                                        c = tmpNewGroupAry[index_01]
                                    }
                                }
                            }
                        }
                        newGroupAry.push(c);
                    }
                    that.groupItemArray = newGroupAry;
                },

                /**
                 * 验证重复
                 * @param index 所属一级索引
                 * @param key 需要判断的code
                 * @returns {boolean} 返回真与假
                 */
                onlyCode: function (index, key) {
                    let that = this;
                    for (let item in that.groupArray[index].type) {
                        if (item === key) {
                            return true;
                        }
                    }
                    return false;
                },

                /**
                 * 笛卡尔积算法sku
                 * @param list
                 * @returns {[]|*}
                 */
                descartes: function (list) {
                    let point = {},
                        result = [],
                        pIndex = null,
                        tempCount = 0,
                        temp = [];

                    // 根据参数列生成指针对象
                    for (let index in list) {
                        if (list.hasOwnProperty(index)) {
                            if (typeof list[index] == 'object') {
                                // parent上一级索引;count指针计数
                                point[index] = { 'parent': pIndex, 'count': 0 };
                                pIndex = index;
                            }
                        }
                    }

                    // 单维度数据结构直接返回
                    if (pIndex === null) {
                        return list;
                    }

                    // 动态生成笛卡尔积
                    while (true) {
                        let index = 0;
                        for (index in list) {
                            if (list.hasOwnProperty(index)) {
                                tempCount = point[index]['count'];
                                temp.push(list[index][tempCount]);
                            }
                        }

                        //压入结果数组
                        result.push(temp);
                        temp = [];

                        //检查指针最大值问题
                        while (true) {
                            if (point[index]['count'] + 1 >= list[index].length) {
                                point[index]['count'] = 0;
                                pIndex = point[index]['parent'];
                                if (pIndex == null) {
                                    return result;
                                }
                                //赋值parent进行再次检查
                                index = pIndex;
                            } else {
                                point[index]['count']++;
                                break;
                            }
                        }
                    }
                }
            }
        });
    </script>
</body>

</html>